import time
import os
import asyncio
import requests
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from watchdog.events import PatternMatchingEventHandler
from logger import logger
from shutil import copy
import yaml

config_file = r'/conf.yaml'

def get_obj_path():
    current_path = os.getcwd()
    doc_path = os.path.dirname(__file__)
    re = doc_path
    if doc_path == '.':
        re = current_path + "/" + os.path.dirname(__file__)
    return re

# 获取yaml文件中的数据：
#     3.get_obj_path() + yamlpath：使用的时候，是项目的路径 + yaml文件的路径
#     4.打开yaml文件，取别名为：f
#     5.获取yaml的文件流，将yaml文件中的数据返回
def read_yaml(yamlpath):
    filepath = get_obj_path() + yamlpath
    if os.path.exists(filepath):
        print( f'Found config : {filepath}' )
        with open( filepath ,mode='r',encoding='utf-8') as f:
            value = yaml.load(stream=f,Loader=yaml.FullLoader)
            return value
    else:
        return None
    
async def send_message( msg ):
    config = sys_config
    send = config.get('send_message')
    token = config.get('dtk_token')
    if send:
        await requests.get('http://101.37.204.55/?tkurl=https://oapi.dingtalk.com/robot/send?access_token=25a9dee4635678f1b81bd77697c0e215ad4aac8c43407425dab0ac73eeef814a&ats=13564302647,13671516032&msg={0}'.format(msg))
    if token:
        await requests.get('http://101.37.204.55/?tkurl=https://oapi.dingtalk.com/robot/send?access_token={1}&ats=13564302647,13671516032&msg={0}'.format(msg,token))

def get_bak_topath(srcpath):
    # global sys_config
    back_path = srcpath

    watchs = sys_config.get('watch_path')
    for watch in watchs:
        if watch in back_path:
            parent_dir = os.path.split(watch)[1]
            back_path = back_path.replace(watch, backup_path + f'/{parent_dir}')
    return back_path

def get_restore_path(srcpath):
    # global sys_config
    restore = srcpath

    watchs = sys_config.get('watch_path')
    for watch in watchs:
        if watch in restore:
            parent_dir = os.path.split(watch)[1]
            restore = restore.replace(watch, restore_path + f'/{parent_dir}')
    return restore

timer = 0
sys_config = read_yaml(config_file)
restore_path = sys_config.get('restore_source')
backup_path = sys_config.get('backup_path')

running = ""
class MyHandler(PatternMatchingEventHandler):
    patterns = ["*.py", "*.php"]

    def __init__(self):
        self.emit_once = True
        super().__init__()

    def on_deleted(self, event):
        global timer
        if event.is_directory:
            return    
        if time.time() - timer > .1:
            # do something
            timer = time.time()
        else: 
            print(f'File deleted: {event.src_path}') 
            return

    def on_moved(self, event):
        if event.is_directory: 
            return
        print(f'File moved: from {event.src_path} to {event.dest_path}')

    def on_created(self, event): 
        global timer 
        if event.is_directory:
            return
        if time.time() - timer > .1:
            msg = f'文件被创建:\n{event.src_path}'
            logger.debug(f'File created: in {event.src_path}')
            if os.path.exists(event.src_path):
                os.remove(event.src_path)
                logger.debug(f'File 【Del Suc】 created: [{event.src_path}]')
                msg = msg + '[删除成功]'
            # print(f'File created: in {event.src_path}')
            asyncio.run(send_message(msg))
            timer = time.time()
        else: 
            return

    def on_modified(self, event):
        global timer,restore_path,backup_path, running
        # print(f'event.is_directory:{event.is_directory}')
        if event.is_directory:
            return
        if time.time() - timer > .1:
            print(f'{running} === {event.src_path}')
            if running == event.src_path:
                return
            running = event.src_path

            logger.debug(f'File modified: in {event.src_path}')
            msg = f'文件改动:\n {event.src_path}'
            src_path = event.src_path
            if backup_path:
                target = get_bak_topath(src_path)
                if not os.path.exists(os.path.dirname(target)):
                    os.makedirs(os.path.dirname(target))
                try:
                    copy(src_path, target)
                    msg = msg + '[备份成功]'
                    logger.debug(f'【backup Suc】 modified Success: [from:{src_path}][to:{target}]') 
                except:
                    msg = msg + '[备份失败]'
                    logger.error(f'【backup Fail】 modified Fail: [from:{src_path}][to:{target}]') 
            if restore_path:
                target = get_restore_path(src_path)
                if os.path.exists(target):
                    try:
                        copy(target, src_path)
                        msg = msg + '[恢复成功]'
                        logger.debug(f'【Restore Suc】 modified Success: [from:{target}][to:{src_path}]') 
                    except:
                        msg = msg + '[恢复失败]'
                        logger.error(f'【Restore Fail】 modified Fail: [from:{target}][to:{src_path}]') 
                else:
                    msg = msg + '[恢复失败]'
                    logger.error(f'【Restore Nosrc】 modified Fail: [{target}]')
            asyncio.run(send_message(msg))
            running = ""
            timer = time.time()
        else: 
            return

    
if __name__ == "__main__":
    data = sys_config
    if not data:
        data = {"watch_path": "."}
    mirropath = data.get('watch_path')
    # path = "D:/ASPACE/DLZ/bak.gentlebands.com_DyrPyc/bak.gentlebands.com/scripts"  # 要监视的目录
    # event_handler = MyHandler()
    observer = Observer()
    dirs = None
    if isinstance(mirropath, str):
        dirs = [mirropath]
    else:
        dirs = mirropath

    for dir in dirs:
        event_handler = MyHandler()
        observer.schedule(event_handler, dir, True)
        logger.debug(f'Watch【start】 Start: {dir}')

    # observer.schedule(event_handler, path, recursive=False)
    observer.start()
 
    try:
        while True:
            time.sleep(1)
    finally:
        observer.stop()

    observer.join()